<template>
  <basicModal
    @register="modalRegister"
    ref="modalRef"
    class="basicModal basicFormModal"
    @on-ok="okModal"
  >
    <template #default>
      <n-form
        :model="formParams"
        :rules="rules"
        ref="formRef"
        label-placement="left"
        :label-width="80"
        class="mt-6"
      >
        <n-form-item label="类型" path="notice_type">
          <n-radio-group v-model:value="formParams.notice_type" name="noticeTypeGroup">
            <n-space>
              <n-radio v-for="item in noticeTypeGroup" :key="item.value" :value="item.value">
                {{ item.label }}
              </n-radio>
            </n-space>
          </n-radio-group>
        </n-form-item>

        <n-form-item label="标题" path="title">
          <n-input placeholder="请输入标题" v-model:value="formParams.title" />
        </n-form-item>

        <n-form-item label="内容" path="content">
          <div class="editor-container">
            <Toolbar
              style="border-bottom: 1px solid #ccc"
              :editor="editorRef"
              :defaultConfig="toolbarConfig"
              :mode="mode"
            />
            <Editor
              style="height: 350px; overflow-y: hidden"
              v-model="formParams.content"
              :defaultConfig="editorConfig"
              :mode="mode"
              @onCreated="handleCreated"
            />
          </div>
        </n-form-item>

        <n-form-item label="接收者" path="receive_type">
          <n-radio-group v-model:value="formParams.receive_type" name="receiveTypeGroup">
            <n-space>
              <n-radio v-for="item in receiveTypeGroup" :key="item.value" :value="item.value">
                {{ item.label }}
              </n-radio>
            </n-space>
          </n-radio-group>
        </n-form-item>

        <n-form-item label="选择部门" path="dept_ids" v-if="formParams.receive_type === 2">
          <n-tree-select
            label-field="dept_name"
            value-field="dept_id"
            key-field="dept_id"
            :options="deptList"
            multiple
            clearable
            v-model:value="formParams.dept_ids"
            placeholder="请选择部门"
          />
        </n-form-item>
      </n-form>
    </template>
    <template #centerFooter>
      <n-button type="warning" @click="saveDraft">保存草稿</n-button>
    </template>
  </basicModal>
</template>

<script lang="ts" setup>
  import { onBeforeUnmount, reactive, ref, shallowRef } from 'vue';

  import { useMessage } from 'naive-ui';
  import type { formParamsType } from './types';
  import { deptTreeList } from '@/api/auth/dept';
  import { basicModal, useModal } from '@/components/Modal';
  import { addNotice, editNotice, noticeInfo } from '@/api/notice/notice';

  import '@wangeditor/editor/dist/css/style.css'; // 引入 css

  import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
  import { useUserStoreWidthOut } from '@/store/modules/user';
  import { useGlobSetting } from '@/hooks/setting';

  const rules = {
    notice_type: {
      required: true,
      type: 'number',
      message: '类型不能为空',
      trigger: 'blur',
    },
    title: {
      required: true,
      message: '标题不能为空',
      trigger: 'blur',
    },
    content: {
      required: true,
      message: '内容不能为空',
      trigger: 'blur',
    },
    dept_ids: {
      required: true,
      message: '部门不能为空',
      trigger: 'change',
      type: 'array',
    },
  };

  const emit = defineEmits(['change', 'register']);

  const props = defineProps({
    title: {
      type: String,
      default: '添加岗位',
    },
    width: {
      type: Number,
      default: 450,
    },
  });

  const noticeTypeGroup = [
    {
      value: 1,
      label: '公告',
    },
    {
      value: 2,
      label: '会议',
    },
    {
      value: 3,
      label: '其他',
    },
  ];

  const receiveTypeGroup = [
    {
      value: 1,
      label: '全部',
    },
    {
      value: 2,
      label: '部门',
    },
  ];

  const message = useMessage();
  const formRef: any = ref(null);
  const isDrawer = ref(false);
  const deptList = ref<any[]>();
  const userStore = useUserStoreWidthOut();
  const token = userStore.getToken;

  const [modalRegister, { openModal, closeModal, setSubLoading }] = useModal({
    title: props.title,
    subBtuText: '发布通知',
    width: 950,
  });

  const defaultValueRef = () => ({
    notice_id: null,
    dept_ids: [],
    notice_status: 1,
    notice_type: 1,
    receive_type: 1,
    content: '',
    title: '',
  });

  const formParams = ref<formParamsType>(defaultValueRef());

  // 编辑器实例，必须用 shallowRef
  const editorRef = shallowRef();
  const globSetting = useGlobSetting();
  const mode = ref('default'); // 或 'simple'
  const { uploadUrl, imgUrl } = globSetting;
  const uploadHeaders = reactive({
    Authorization: `Bearer ${token}`,
  });

  // 内容 HTML
  const valueHtml = ref(formParams.value.content);

  type InsertFnType = (url: string, alt?: string, href?: string) => void;

  const toolbarConfig = {};
  const editorConfig = reactive({
    MENU_CONF: {
      uploadImage: {
        fieldName: 'file',
        headers: uploadHeaders,
        meta: {
          type: 0,
        },
        server: `${uploadUrl}/api/common/upload`,
        // 自定义插入图片
        customInsert(res: any, insertFn: InsertFnType) {
          // res 即服务端的返回结果
          // 从 res 中找到 url alt href ，然后插图图片
          if (res.code === 200) {
            insertFn(imgUrl + res.data.filePath);
          }
        },
      },
    },
    placeholder: '请输入内容...',
  });

  // 组件销毁时，也及时销毁编辑器
  onBeforeUnmount(() => {
    const editor = editorRef.value;
    if (editor == null) return;
    editor.destroy();
  });

  const handleCreated = (editor) => {
    editorRef.value = editor; // 记录 editor 实例，重要！
  };

  async function showModal(notice_id?) {
    const deptResList = await deptTreeList();
    deptList.value = deptResList;
    if (notice_id) {
      formParams.value.notice_id = notice_id;
      getInfo();
      return;
    }
    openModal();
  }

  function saveDraft() {
    formParams.value.notice_status = 2;
    okModal();
  }

  function okModal() {
    formRef.value.validate((errors) => {
      if (!errors) {
        const msg = formParams.value.notice_id ? '编辑成功' : '添加成功';
        if (formParams.value.notice_id) {
          editNotice(formParams.value)
            .then((_) => {
              message.success(msg);
              setSubLoading(false);
              emit('change');
              handleReset();
              closeModal();
            })
            .catch(() => {
              setSubLoading(false);
            });
        } else {
          addNotice(formParams.value)
            .then((_) => {
              message.success(msg);
              setSubLoading(false);
              emit('change');
              handleReset();
              closeModal();
            })
            .catch(() => {
              setSubLoading(false);
            });
        }
      } else {
        setSubLoading(false);
        message.error('请填写完整信息');
      }
    });
  }

  function handleReset() {
    formRef.value.restoreValidation();
    formParams.value = Object.assign(formParams.value, defaultValueRef());
  }

  function getInfo() {
    noticeInfo({ id: formParams.value.notice_id }).then((res) => {
      const params = {
        notice_id: res.notice_id,
        dept_ids: res.dept_ids,
        notice_status: res.notice_status,
        notice_type: res.notice_type,
        receive_type: res.receive_type,
        title: res.title,
        content: res.content,
      };
      formParams.value = Object.assign(formParams.value, params);
      isDrawer.value = true;
      valueHtml.value = res.content;
    });
  }

  defineExpose({
    showModal,
    closeModal,
  });
</script>

<style lang="less" scoped>
  .editor-container {
    border: 1px solid #e5e7eb;
    z-index: 100;
    dl,
    dd,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    hr,
    figure,
    p,
    pre {
      margin: revert;
    }
    h1,
    h2,
    h3,
    h4,
    h5,
    h6 {
      font-size: revert;
      font-weight: revert;
    }
    ul {
      list-style: circle;
      margin: revert;
      padding: revert;
    }
  }
</style>
